def get_session_mon(db_name):
"""
:param db_name: Nombre de la base de datos de los incidentes y los distritos
:return: Objeto de tipo DataBase con una conexión a la base de datos local
"""
client = MongoClient()
db = client[db_name]
return db
def total_per_hour(db):
"""
Esta función usa el framework de aggregate para obtener el total de incidentes de cada hora
:param db: referencia a la sesión de bd
:return: Dataframe composed of two columns, hours of the day and count of total incidents in that hour
"""
# Primero proyectamos cada documento en otro sacando solo el _id y la hora
pipeline = [
{"$project": { "h": { "$hour": "$Date" } }}, # nuevo campo h que ha sido proyecto desde la fecha
{"$group": {"_id": "$h", "count": {"$sum": 1}}},
{"$sort": SON([("_id", 1), ("count", 1)])}
]
aggregate_results = db.incidents.aggregate(pipeline)
df = pd.DataFrame(list(aggregate_results))
return df
def total_per_category(db):
"""
Esta función usa el framework de aggregate para obtener el total de cada categorĆa
:param db: referencia a la sesión de bd
:return: Dataframe composed of two columns, categories and count of each category
"""
#Agrupamos por categorĆa y los contamos, y luego ordenamos
pipeline = [
{"$group": {"_id": "$Category", "count": {"$sum": 1}}},
{"$sort": SON([("count", -1), ("_id", -1)])}
]
aggregate_results = db.incidents.aggregate(pipeline)
df = pd.DataFrame(list(aggregate_results))
return df
def date_querry_mon(op, sdate, edate):
"""
:param opr: operador B: between dates, L: less than, G: greater than
:return: devuelve el filtro de la consulta según lo que se recibe por parÔmetro
en op
"""
switcher = {
'B': {"Date": {"$gte": sdate, "$lte": edate}}, # Between
'GE': {"Date": {"$gte": sdate}}, # Greater than or equal
'LE': {"Date": {"$lte": sdate}}, # less than or equal
}
return switcher.get(op)
def generic_date_search_mon(db, op, sdate, *args, **kwargs):
"""
:param db: referencia a la sesión de bd
:param op: operador para seleccionar
:param sdate: primera fecha, mandaterio
:param args:
:param kwargs: Contiene argumento opcional de la seguna fecha
:return: incidentes que cumplen con el filtro sobre fechas
"""
edate = kwargs.get('edate', None)
if not edate is None:
query = date_querry_mon(op, sdate, edate)
else:
query = date_querry_mon(op, sdate, None)
query_results = db.incidents.find(query)
df = pd.DataFrame(list(query_results))
return df
def since_february_mon(db):
"""
:param db: referencia a la sesión de la bd
:return: Devuelve los incidentes que han ocurrido desde febrero de 2018
"""
fecha = datetime(2018, 2, 1)
incidents = db.incidents.find({"Date": {"$gt": fecha}})
df = pd.DataFrame(list(incidents))
return df
def draw_map(ds, save_file=None):
"""
Esta función recibe un conjunto de incidentes y los dibuja en un mapa usando el paquete folium,
el mapa se guarda en un fichero.
:param ds: dataset de incidentes en formato de DataFrame
"""
incid_map = folium.Map(location=[37.7617007179518, -122.42158168136999], zoom_start=11, tiles='Stamen Terrain')
marker_cluster = plugins.MarkerCluster().add_to(incid_map)
for name, row in ds.iterrows():
folium.Marker([row["Y"], row["X"]], popup=row["Descript"]).add_to(marker_cluster)
if save_file is True:
folium.Marker([37.7883306, -122.4447861], popup='Centro del perĆmetro').add_to(incid_map)
incid_map.save('incidents.html')
return incid_map
def draw_heatmap(df):
"""
Esta función recibe un conjunto de incidentes y los dibuja en un mapa de calor que
se guarda en un fichero html
:param ds: dataset de incidentes en formato de DataFrame
"""
heat_map = folium.Map(location=[37.7617007179518, -122.42158168136999], zoom_start=11, tiles='Stamen Terrain')
heat_map.add_child(plugins.HeatMap([[row["Y"], row["X"]] for name, row in df.iterrows()]))
return heat_map
def total_mes(db):
# Primero proyectamos cada documento en otro sacando solo el _id y la hora
pipeline = [
{"$project": { "m": { "$month": "$Date" } }}, # nuevo campo m que ha sido proyecto desde la fecha
{"$group": {"_id": "$m", "count": {"$sum": 1}}},
{"$sort": SON([("_id", 1), ("count", 1)])}
]
aggregate_results = db.incidents.aggregate(pipeline)
df = pd.DataFrame(list(aggregate_results))
return df
def geo_within(db):
"""
:param db: referencia a la sesión de la bd
:return: Esta función obtiene los incidentes que estÔn a una distancia mÔximo de 1000 metros
desde un punto representado por coordinadas geogrƔficas en formato geojson
"""
# Montamos la query
query_incidents = {
"Location" :{
"$near": {
"$geometry" : SON([
("type", "Point"),
("coordinates", [-122.4447861, 37.7883306])
]),
"$maxDistance": 1000,
"$minDistance": 500
}
}
}
# Ejecutamos la querry sobre la colección de incidencias
query_results = db.incidents.find(query_incidents)
df = pd.DataFrame(list(query_results))
return df